#include "stdafx.h"
#include "WebBrowserAPI.h"

#include <cassert>


HRESULT CreateBrowser(const RECT* prcWnd, HWND hWndParent, CAiOleClientSite* pOleClientSite, IOleObject** pBrowserObjResult)
{
    if(FAILED(OleInitialize(NULL)))
        return FALSE;

    HRESULT         hr             = S_OK;
    LPCLASSFACTORY  pClassFactory  = NULL;
//    IWebBrowser2*   pBrowser2      = NULL;
    IOleObject*     pBrowserObj    = NULL;

    *pBrowserObjResult = NULL;

    pOleClientSite->SetParent(hWndParent);

    do
    {
        hr = CoGetClassObject(CLSID_WebBrowser, CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, NULL, IID_IClassFactory, (void **)&pClassFactory);
        if(FAILED(hr) || pClassFactory == NULL)
            break;

        hr = pClassFactory->CreateInstance(0, IID_IOleObject, (void**)&pBrowserObj);
        if(FAILED(hr) || pBrowserObj == NULL)
            break;

        hr = pBrowserObj->SetClientSite(pOleClientSite);
        if(FAILED(hr))
            break;

        hr = pBrowserObj->SetHostNames(_T("AiWebBrowser"), 0);
        if(FAILED(hr))
            break;

        hr = OleSetContainedObject((IUnknown*)pBrowserObj, TRUE);
        if(FAILED(hr))
            break;

        hr = pBrowserObj->DoVerb(OLEIVERB_SHOW, NULL, (IOleClientSite *)pOleClientSite, -1, hWndParent, prcWnd);
        if(FAILED(hr))
            break;

//         hr = pBrowserObj->QueryInterface(IID_IWebBrowser2, (void**)&pBrowser2);
//         if(FAILED(hr))
//             break;

    }while (FALSE);

    if(pClassFactory != NULL)
    {
        pClassFactory->Release();
        pClassFactory = NULL;
    }

    if(pBrowserObj != NULL)
    {
        *pBrowserObjResult = pBrowserObj;
//         pBrowserObj->Release();
//         pBrowserObj = NULL;
    }

    return hr;
}

DWORD AttachEventHandler(IOleObject* pBrowserObj, IDispatch* pEventSink)
{
    assert(pBrowserObj != NULL);
    if(pBrowserObj == NULL)
        return 0;

    DWORD dwCookie = 0;
    LPCONNECTIONPOINT pConnPt = NULL;
    LPCONNECTIONPOINTCONTAINER pConnPtCont = NULL;

    do 
    {
        if(FAILED(pBrowserObj->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pConnPtCont)) || pConnPtCont == NULL)
            break;

        if(FAILED(pConnPtCont->FindConnectionPoint(DIID_DWebBrowserEvents2, &pConnPt)) || pConnPt == NULL)
            break;

        pConnPt->Advise(pEventSink, &dwCookie);

    } while (FALSE);

    if(pConnPt != NULL)
    {
        pConnPt->Release();
        pConnPt = NULL;
    }
    if(pConnPtCont != NULL)
    {
        pConnPtCont->Release();
        pConnPtCont = NULL;
    }

    return dwCookie;
}

HRESULT DetachEventHandler(IOleObject* pBrowserObj, DWORD dwCookie)
{
    assert(pBrowserObj != NULL && dwCookie != 0);
    if(pBrowserObj == NULL || dwCookie == 0)
        return E_INVALIDARG;

    HRESULT hr = S_OK;
    LPCONNECTIONPOINT pConnPt = NULL;
    LPCONNECTIONPOINTCONTAINER pConnPtCont = NULL;

    do 
    {
        if(FAILED(pBrowserObj->QueryInterface(IID_IConnectionPointContainer, (LPVOID*)&pConnPtCont)) || pConnPtCont == NULL)
            break;

        if(FAILED(pConnPtCont->FindConnectionPoint(DIID_DWebBrowserEvents2, &pConnPt)) || pConnPt == NULL)
            break;

        hr = pConnPt->Unadvise(dwCookie);

    } while (FALSE);

    if(pConnPt != NULL)
    {
        pConnPt->Release();
        pConnPt = NULL;
    }
    if(pConnPtCont != NULL)
    {
        pConnPtCont->Release();
        pConnPtCont = NULL;
    }

    return hr;
}

HWND GetWebBrowserHWnd(IOleObject* pBrowserObj)
{
    HWND hWnd = NULL;
    assert(pBrowserObj != NULL);
    if(pBrowserObj == NULL)
        return hWnd;

    IOleWindow* pOleWindow = NULL;
    HRESULT hResult = pBrowserObj->QueryInterface(IID_IOleWindow, (void**)&pOleWindow);
    if(SUCCEEDED(hResult) && pOleWindow != NULL)
    {
        pOleWindow->GetWindow(&hWnd);
        pOleWindow->Release();
    }

    return hWnd;
}